# backend/core/image_processor.py
from PIL import Image, ImageFilter, ImageEnhance, ImageDraw
import os
from pathlib import Path
import random
import logging

logger = logging.getLogger(__name__)


class CaptchaImageProcessor:
    def __init__(self, source_dir, output_dir):
        self.source_dir = Path(source_dir)
        self.output_dir = Path(output_dir)
        self.backgrounds_dir = self.output_dir / "backgrounds"
        self.sliders_dir = self.output_dir / "sliders"

        # 显示目录路径
        print(f"源图片目录: {self.source_dir.absolute()}")
        print(f"输出目录: {self.output_dir.absolute()}")
        print(f"背景图目录: {self.backgrounds_dir.absolute()}")
        print(f"滑块图目录: {self.sliders_dir.absolute()}")

        # 检查源目录是否存在
        if not self.source_dir.exists():
            print(f"警告: 源目录不存在: {self.source_dir}")
            raise FileNotFoundError(f"源目录不存在: {self.source_dir}")

        # 创建输出目录
        self.backgrounds_dir.mkdir(parents=True, exist_ok=True)
        self.sliders_dir.mkdir(parents=True, exist_ok=True)

    def process_matching_images(self, max_groups=10):
        """处理源图片，生成对应的背景图和滑块图"""
        print("开始生成对应的验证码图片组...")

        source_images = list(self.source_dir.glob("*.[jp][pn]g")) + list(self.source_dir.glob("*.[jp][pn]eg"))
        print(f"找到 {len(source_images)} 张源图片")

        if len(source_images) == 0:
            print("没有找到源图片")
            return 0, 0

        groups_created = 0

        for i, img_path in enumerate(source_images):
            if groups_created >= max_groups:
                break

            try:
                group_id = f"group_{groups_created + 1:02d}"
                print(f"处理第 {groups_created + 1} 组: {img_path.name}")

                # 处理单张图片生成一组验证码
                bg_count, slider_count = self._process_single_image_group(img_path, group_id)
                groups_created += 1

            except Exception as e:
                print(f"处理图片组失败 {img_path.name}: {e}")

        print(f"处理完成: 共生成 {groups_created} 组验证码图片")
        return groups_created * 1, groups_created * 4  # 每组1张背景图，4张滑块图

    def _process_single_image_group(self, img_path, group_id):
        """从单张源图片生成一组对应的验证码图片"""
        try:
            with Image.open(img_path) as img:
                img = img.convert('RGB')

                # 生成背景图
                bg = self._create_background_from_source(img)

                # 生成4个对应的滑块位置
                slider_positions = self._generate_slider_positions(4)

                # 保存背景图（不带缺口）
                bg_path = self.backgrounds_dir / f"{group_id}_bg.jpg"
                bg.save(bg_path, "JPEG", quality=85)
                print(f"生成背景图: {bg_path.name}")

                # 为每个位置生成对应的滑块，并记录位置信息
                for j, (x, y) in enumerate(slider_positions):
                    # 从背景图中裁剪滑块区域
                    slider = self._create_slider_from_background(bg, x, y)
                    if slider:
                        # 在文件名中包含位置信息
                        slider_path = self.sliders_dir / f"{group_id}_slider_{j + 1}_pos{x}.png"
                        slider.save(slider_path, "PNG")
                        print(f"生成滑块图: {slider_path.name}, 位置: ({x}, {y})")

        except Exception as e:
            print(f"处理单张图片组失败: {e}")
            return 0, 0

        return 1, len(slider_positions)

    def _generate_slider_positions(self, count):
        """生成滑块位置"""
        positions = []
        # 合理的x位置（确保滑块在背景图内）
        x_positions = [40, 100, 160, 220]
        y_position = 60  # 固定的y位置

        for i in range(min(count, 4)):
            positions.append((x_positions[i], y_position))

        return positions

    def _create_slider_from_background(self, bg_image, x, y):
        """从背景图中创建对应的滑块"""
        slider_width, slider_height = 50, 30

        # 从背景图中裁剪滑块区域
        slider_region = bg_image.crop((x, y, x + slider_width, y + slider_height))

        # 创建带形状的滑块
        slider = self._create_slider_with_shape(slider_region)

        return slider

    def _create_slider_with_shape(self, slider_region):
        """创建带形状的滑块"""
        slider_width, slider_height = 50, 30

        # 创建圆角矩形蒙版
        mask = Image.new('L', (slider_width, slider_height), 0)
        draw = ImageDraw.Draw(mask)

        # 绘制圆角矩形
        radius = 8
        # 主体矩形
        draw.rectangle([radius, 0, slider_width - radius, slider_height], fill=255)
        draw.rectangle([0, radius, slider_width, slider_height - radius], fill=255)
        # 四个圆角
        draw.ellipse([0, 0, radius * 2, radius * 2], fill=255)
        draw.ellipse([slider_width - radius * 2, 0, slider_width, radius * 2], fill=255)
        draw.ellipse([0, slider_height - radius * 2, radius * 2, slider_height], fill=255)
        draw.ellipse([slider_width - radius * 2, slider_height - radius * 2, slider_width, slider_height], fill=255)

        # 应用形状
        slider = Image.new('RGBA', (slider_width, slider_height))
        slider.putalpha(mask)
        slider_rgb = Image.new('RGB', (slider_width, slider_height))
        slider_rgb.paste(slider_region, (0, 0))
        slider.paste(slider_rgb, (0, 0), mask)

        # 添加边框效果
        slider = self._add_slider_border(slider)

        return slider

    def _create_background_from_source(self, img):
        """从源图片创建背景图"""
        # 调整尺寸为300x150，保持宽高比并进行裁剪
        bg = self._resize_and_crop(img, 300, 150)

        # 增强图片效果
        bg = self._enhance_background(bg)

        return bg

    def _resize_and_crop(self, img, target_width, target_height):
        """调整图片尺寸并裁剪到目标大小"""
        width, height = img.size
        target_ratio = target_width / target_height

        if width / height > target_ratio:
            new_height = target_height
            new_width = int(width * target_height / height)
        else:
            new_width = target_width
            new_height = int(height * target_width / width)

        img_resized = img.resize((new_width, new_height), Image.Resampling.LANCZOS)
        left = (new_width - target_width) // 2
        top = (new_height - target_height) // 2
        right = left + target_width
        bottom = top + target_height

        return img_resized.crop((left, top, right, bottom))

    def _enhance_background(self, img):
        """增强背景图片效果"""
        enhancer = ImageEnhance.Brightness(img)
        img = enhancer.enhance(random.uniform(0.8, 1.2))

        enhancer = ImageEnhance.Contrast(img)
        img = enhancer.enhance(random.uniform(0.9, 1.1))

        enhancer = ImageEnhance.Color(img)
        img = enhancer.enhance(random.uniform(0.9, 1.1))

        img = img.filter(ImageFilter.GaussianBlur(radius=0.5))
        return img

    def _add_slider_border(self, slider):
        """为滑块添加边框效果"""
        border_size = 2
        new_size = (slider.width + border_size * 2, slider.height + border_size * 2)
        bordered = Image.new('RGBA', new_size, (0, 0, 0, 0))
        draw = ImageDraw.Draw(bordered)

        # 添加白色边框
        border_color = (255, 255, 255, 200)
        # 绘制圆角矩形边框
        radius = 10
        # 主体矩形
        draw.rectangle([radius, 0, new_size[0] - radius, new_size[1]], fill=border_color)
        draw.rectangle([0, radius, new_size[0], new_size[1] - radius], fill=border_color)
        # 四个圆角
        draw.ellipse([0, 0, radius * 2, radius * 2], fill=border_color)
        draw.ellipse([new_size[0] - radius * 2, 0, new_size[0], radius * 2], fill=border_color)
        draw.ellipse([0, new_size[1] - radius * 2, radius * 2, new_size[1]], fill=border_color)
        draw.ellipse([new_size[0] - radius * 2, new_size[1] - radius * 2, new_size[0], new_size[1]], fill=border_color)

        bordered.paste(slider, (border_size, border_size), slider)
        return bordered


def generate_matching_captcha_images(source_folder, output_folder="static/captcha"):
    """生成对应的验证码图片的主函数"""
    processor = CaptchaImageProcessor(source_folder, output_folder)
    return processor.process_matching_images()


def generate_complete_matching_images(source_folder="D:\\download\\images", output_folder="static/captcha"):
    """完整的对应图片生成流程"""
    print("=" * 50)
    print("开始生成对应的验证码图片...")
    print("=" * 50)

    try:
        # 处理下载的图片，生成对应的背景图和滑块图
        bg_count, slider_count = generate_matching_captcha_images(source_folder, output_folder)

        print("=" * 50)
        print(f"最终结果: {bg_count}张背景图, {slider_count}张滑块图")
        print("=" * 50)
        return bg_count, slider_count

    except FileNotFoundError as e:
        print(f"错误: {e}")
        print("请确保源图片目录存在并包含图片文件")
        return 0, 0
    except Exception as e:
        print(f"生成过程出错: {e}")
        return 0, 0


if __name__ == "__main__":
    generate_complete_matching_images()